import httpx
import base64
from typing import List, Optional
from pathlib import Path
from app.config import settings
from app.utils.logger import logger
import json

class InternVLService:
    def __init__(self):
        self.api_key = settings.INTERNVL_API_KEY
        self.base_url = settings.INTERNVL_BASE_URL
        self.headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
    
    async def analyze_video_direct(self, video_b64: str, video_mime_type: str, prompt: str) -> str:
        """使用InternVL3.5直接分析视频"""
        
        # 尝试多种视频数据格式
        video_formats = [
            # 格式1: video_url类型（如果支持）
            {
                "name": "video_url格式",
                "data": {
                    "type": "video_url",
                    "video_url": {
                        "url": f"data:{video_mime_type};base64,{video_b64}"
                    }
                },
                "prompt_prefix": "<video>\
"
            },
            # 格式2: image_url类型（作为备选）
            {
                "name": "image_url格式", 
                "data": {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:{video_mime_type};base64,{video_b64}"
                    }
                },
                "prompt_prefix": ""
            }
        ]
        
        # 依次尝试不同格式
        for format_info in video_formats:
            try:
                logger.info(f"尝试使用 {format_info['name']} 进行视频分析")
                
                # 构建请求消息
                messages = [
                    {
                        "role": "user",
                        "content": [
                            {
                                "type": "text",
                                "text": f"{format_info['prompt_prefix']}{prompt}"
                            },
                            format_info["data"]
                        ]
                    }
                ]
                
                # 构建请求体
                request_data = {
                    "model": settings.INTERNVL_MODEL_NAME,
                    "messages": messages,
                    "stream": False,
                    "max_tokens": 2000,
                    "temperature": 0.7
                }
                
                logger.info(f"发送InternVL直接视频分析请求，视频大小: {len(video_b64)} chars")
                
                # 发送请求
                async with httpx.AsyncClient(timeout=120.0) as client:
                    response = await client.post(
                        f"{self.base_url}/chat/completions",
                        headers=self.headers,
                        json=request_data
                    )
                    
                    if response.status_code == 200:
                        result = response.json()
                        logger.info(f"API响应成功: {format_info['name']}")
                        
                        # 提取分析结果
                        if "choices" in result and len(result["choices"]) > 0:
                            analysis_text = result["choices"][0]["message"]["content"]
                            logger.info(f"InternVL直接视频分析完成 ({format_info['name']})")
                            return analysis_text
                        else:
                            logger.warning(f"{format_info['name']} 返回格式异常: {result}")
                            continue
                    else:
                        logger.warning(f"{format_info['name']} 请求失败: {response.status_code} - {response.text}")
                        continue
                        
            except Exception as e:
                logger.warning(f"{format_info['name']} 分析失败: {str(e)}")
                continue
        
        # 所有格式都失败
        raise Exception("所有视频格式都分析失败，请检查视频文件或API配置")
    
    async def analyze_video_frames(self, frames: List[bytes], prompt: str) -> str:
        """使用InternVL3.5分析视频帧（备用方法）"""
        try:
            # 将视频帧转换为base64
            frame_data = []
            for i, frame in enumerate(frames[:8]):  # 最多取8帧
                frame_b64 = base64.b64encode(frame).decode('utf-8')
                frame_data.append({
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/jpeg;base64,{frame_b64}"
                    }
                })
            
            # 构建请求消息
            messages = [
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "text",
                            "text": prompt
                        }
                    ] + frame_data
                }
            ]
            
            # 构建请求体
            request_data = {
                "model": settings.INTERNVL_MODEL_NAME,
                "messages": messages,
                "stream": False,
                "max_tokens": 2000,
                "temperature": 0.7
            }
            
            logger.info(f"发送InternVL帧分析请求，帧数: {len(frame_data)}")
            
            # 发送请求
            async with httpx.AsyncClient(timeout=60.0) as client:
                response = await client.post(
                    f"{self.base_url}/chat/completions",
                    headers=self.headers,
                    json=request_data
                )
                
                if response.status_code != 200:
                    logger.error(f"InternVL API错误: {response.status_code} - {response.text}")
                    raise Exception(f"API调用失败: {response.status_code}")
                
                result = response.json()
                
                # 提取分析结果
                if "choices" in result and len(result["choices"]) > 0:
                    analysis_text = result["choices"][0]["message"]["content"]
                    logger.info("InternVL帧分析完成")
                    return analysis_text
                else:
                    raise Exception("API返回格式异常")
                    
        except Exception as e:
            logger.error(f"InternVL帧分析失败: {str(e)}")
            raise Exception(f"视频分析失败: {str(e)}")
    
    async def analyze_text(self, prompt: str) -> str:
        """使用InternVL分析纯文本内容"""
        try:
            logger.info("开始调用InternVL模型分析文本")
            
            # 构建请求数据（纯文本分析）
            request_data = {
                "model": "internvl-chat",
                "messages": [
                    {
                        "role": "user",
                        "content": prompt
                    }
                ],
                "stream": False,
                "max_tokens": 2000,
                "temperature": 0.7
            }
            
            async with httpx.AsyncClient(timeout=300.0) as client:
                logger.info(f"发送文本分析请求到: {self.base_url}")
                
                response = await client.post(
                    f"{self.base_url}/chat/completions",
                    json=request_data,
                    headers=self.headers
                )
                
                logger.info(f"InternVL文本分析响应状态: {response.status_code}")
                
                if response.status_code == 200:
                    result = response.json()
                    
                    # 提取分析结果
                    if 'choices' in result and len(result['choices']) > 0:
                        analysis_result = result['choices'][0].get('message', {}).get('content', '')
                        if analysis_result:
                            logger.info("InternVL文本分析成功")
                            return analysis_result.strip()
                    
                    logger.warning(f"InternVL文本分析响应格式异常: {result}")
                    return "文本分析完成，但响应格式异常"
                else:
                    error_msg = f"InternVL文本分析失败，状态码: {response.status_code}"
                    try:
                        error_detail = response.json()
                        error_msg += f"，错误详情: {error_detail}"
                    except:
                        error_msg += f"，响应内容: {response.text}"
                    
                    logger.error(error_msg)
                    raise Exception(error_msg)
                    
        except httpx.TimeoutException:
            error_msg = "InternVL文本分析超时"
            logger.error(error_msg)
            raise Exception(error_msg)
        except Exception as e:
            logger.error(f"InternVL文本分析异常: {str(e)}")
            raise Exception(f"文本分析失败: {str(e)}")
    
    async def test_connection(self) -> bool:
        """测试API连接"""
        try:
            async with httpx.AsyncClient(timeout=10.0) as client:
                response = await client.get(
                    f"{self.base_url}/models",
                    headers=self.headers
                )
                return response.status_code == 200
        except:
            return False